﻿using IOP.Extension.Convert;
using IOP.Protocols.MQTT.Extension;
using System;

namespace IOP.Protocols.MQTT.Package
{
    /// <summary>
    /// 取消订阅包
    /// </summary>
    public struct UnsubscribePackage : IMQTTPackage
    {
        /// <summary>
        /// 报文类型
        /// </summary>
        public ControlPacketType PacketType { get => ControlPacketType.UNSUBSCRIBE; }

        private uint _RemainingLength;
        /// <summary>
        /// 剩余长度
        /// </summary>
        public uint RemainingLength { get => _RemainingLength + 2; }
        /// <summary>
        /// 报文标识符
        /// </summary>
        public ushort PacketIdentifier;

        private string[] _TopicFilters;
        /// <summary>
        /// 主题过滤器
        /// </summary>
        public string[] TopicFilters
        {
            get
            {
                if (_TopicFilters == null) _TopicFilters = new string[0];
                return _TopicFilters;
            }
            set
            {
                if(_TopicFilters != value)
                {
                    if (_TopicFilters != null) foreach (var item in _TopicFilters) _RemainingLength -= (uint)item.Length + 2;
                    if (value != null)
                    {
                        foreach (var item in value)
                        {
                            if (item.Length > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(TopicFilters), "TopicFilter's length is out of max value 65535");
                            _RemainingLength += (uint)item.Length + 2;
                        }
                        _TopicFilters = value;
                    }
                    else _TopicFilters = new string[0];
                }
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="packetId"></param>
        /// <param name="topicFilters"></param>
        public UnsubscribePackage(ushort packetId, string[] topicFilters)
        {
            _RemainingLength = 0;
            _TopicFilters = new string[0];

            PacketIdentifier = packetId;
            TopicFilters = topicFilters;
        }

        /// <summary>
        /// 转换为字节码
        /// </summary>
        /// <returns></returns>
        public Span<byte> ToBytes()
        {
            int remain = RemainingLength.GetRemainBytesLength();
            var length = RemainingLength + remain + 1;

            Span<byte> result = new byte[length];
            int index = 0;
            result[index++] = (byte)((int)PacketType << 4);
            RemainingLength.WriteRemainLengthToBytes(ref result, ref index);

            PacketIdentifier.WriteBytes(ref result, ref index);

            foreach (var item in TopicFilters) item.SrtingToMqttUTF8Bytes(ref result, ref index);
            return result;
        }
    }
}
